package com.jwt.spring.login.form;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindException;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.util.WebUtils;

import com.jwt.actions.JWTActions;
import com.jwt.dao.bean.Account;
import com.jwt.spring.login.beans.AccountForm;
import com.jwt.spring.login.session.UserSession;

public class AccountFormController extends SimpleFormController {

	public static final String[] LANGUAGES = { "english", "japanese" };

	private JWTActions jwtActions;

	public AccountFormController() {
		setSessionForm(true);
		setValidateOnBinding(false);
		setCommandName("accountForm");
		setFormView("EditAccountForm");
	}

	public void setJWTActions(JWTActions jwtActions) {
		this.jwtActions = jwtActions;
	}

	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		UserSession userSession = (UserSession) WebUtils.getSessionAttribute(
				request, "userSession");
		if (userSession != null) {
			return new AccountForm(this.jwtActions.getAccount(userSession
					.getAccount().getUsername()));
		} else {
			return new AccountForm();
		}
	}

	protected void onBindAndValidate(HttpServletRequest request,
			Object command, BindException errors) throws Exception {

		AccountForm accountForm = (AccountForm) command;
		Account account = accountForm.getAccount();

		errors.setNestedPath("account");
		getValidator().validate(account, errors);
		errors.setNestedPath("");

		if (accountForm.isNewAccount()) {
			account.setStatus("OK");
			ValidationUtils.rejectIfEmpty(errors, "account.username",
					"USER_ID_REQUIRED", "User ID is required.");
			if (account.getPassword() == null
					|| account.getPassword().length() < 1
					|| !account.getPassword().equals(
							accountForm.getRepeatedPassword())) {
				errors
						.reject(
								"PASSWORD_MISMATCH",
								"Passwords did not match or were not provided. Matching passwords are required.");
			}
		} else if (account.getPassword() != null
				&& account.getPassword().length() > 0) {
			if (!account.getPassword()
					.equals(accountForm.getRepeatedPassword())) {
				errors
						.reject("PASSWORD_MISMATCH",
								"Passwords did not match. Matching passwords are required.");
			}
		}
	}

	@SuppressWarnings("unchecked")
	protected Map referenceData(HttpServletRequest request) throws Exception {
		Map model = new HashMap();
		model.put("languages", LANGUAGES);
		return model;
	}

	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {

		AccountForm accountForm = (AccountForm) command;
		try {
			if (accountForm.isNewAccount()) {
				this.jwtActions.insertAccount(accountForm.getAccount());
			} else {
				this.jwtActions.updateAccount(accountForm.getAccount());
			}
		} catch (DataIntegrityViolationException ex) {
			errors.rejectValue("account.username", "USER_ID_ALREADY_EXISTS",
					"User ID already exists: choose a different ID.");
			return showForm(request, response, errors);
		}

		UserSession userSession = new UserSession(this.jwtActions
				.getAccount(accountForm.getAccount().getUsername()));
		request.getSession().setAttribute("userSession", userSession);
		return super.onSubmit(request, response, command, errors);
	}

}
